#include "sqlconpool.h"

void SqlConnPool::init(const char *host, int port,
                       const char *user, const char *pwd,
                       const char *dbName, int connSize)
{
    assert(connSize > 0);
    for (int i = 0; i < connSize; i++)
    {
        MYSQL *sql = nullptr;
        sql = mysql_init(sql);
        if (sql == nullptr)
        {
            LOG_ERROR("Init sql Error");
            assert(sql != nullptr);
        }
        sql = mysql_real_connect(sql, host, user, pwd, dbName, port, nullptr, 0);
        if (sql == nullptr)
        {
            LOG_ERROR("Conn sql error");
            assert(sql != nullptr);
        }
        connQue_.push(sql);
    }
    MaxCount_ = connSize;
    sem_init(&sem_, 0, static_cast<unsigned int>(MaxCount_));
}

MYSQL *SqlConnPool::GetConn()
{
    MYSQL *sql = nullptr;
    if (connQue_.empty())
    {
        LOG_INFO("SQL queue busy!");
        return sql;
    }
    sem_wait(&sem_);
    {
        std::lock_guard<std::mutex> lock(Mtx_);
        sql = connQue_.front();
        connQue_.pop();
    }
    return sql;
}

void SqlConnPool::FreeConn(MYSQL *conn)
{
    assert(conn);
    std::lock_guard<std::mutex> lokc(Mtx_);
    connQue_.push(conn);
    sem_post(&sem_);
}

int SqlConnPool::GetFreeConnCount()
{
    std::lock_guard<std::mutex> lock(Mtx_);
    return static_cast<int>(connQue_.size());
}

SqlConnPool* SqlConnPool::Instance()
{
    static SqlConnPool sqlconnpool;
    return &sqlconnpool;
}

SqlConnPool::SqlConnPool():freeCount_(0),MaxCount_(0),useCount_(0)
{}


SqlConnPool::~SqlConnPool()
{
    Close();
}

void SqlConnPool::Close()
{
    std::lock_guard<std::mutex> lock(Mtx_);
    while(connQue_.size())
    {
        MYSQL *sql = connQue_.front();
        connQue_.pop();
        mysql_close(sql);
    }
    mysql_library_end();
}
